Mlflow converter#16
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an MLflow → FNNX packaging/conversion path, including a static runtime wrapper, environment/signature mapping utilities, verification support, and a broad set of end-to-end tests across multiple ML frameworks.
Changes:
- Introduces
fnnx.extras.mlflow(package_mlflow_model,MLflowConverter) to package MLflow model directories/URIs into FNNX pyfunc packages, including manifest/env/meta generation and optionalverify=Truesmoke tests. - Adds a static
MLflowModelruntime wrapper (fnnx.extras._mlflow_wrapper) that loads MLflow models lazily, assembles inputs byinput_mode, forwards params, and normalizes outputs to JSON-safe data. - Expands test coverage with extensive unit + e2e tests and updates packaging metadata/dependencies (version bump, new optional deps, example script).
Reviewed changes
Copilot reviewed 19 out of 21 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| src/python/fnnx/extras/mlflow.py | Implements MLflow model readers, schema/env mapping, packaging orchestration, and verify workflow. |
| src/python/fnnx/extras/_mlflow_wrapper.py | Adds a static pyfunc wrapper that loads MLflow models at warmup and normalizes inputs/outputs at runtime. |
| src/python/fnnx/extras/builder.py | Adds python_version override support and allows defining extra dtypes via raw dict schemas. |
| src/python/examples/mlflow_to_fnnx.py | Provides a hands-on demo script for converting, inspecting, and running converted packages. |
| src/python/pyproject.toml | Bumps version and adds optional dependency groups for extras/mlflow and expanded test dependencies. |
| src/python/fnnx/init.py | Version bump to 0.0.12. |
| src/python/tests/test_mlflow_wrapper.py | Unit tests for wrapper payload assembly, param passing, warmup behavior, and JSON normalization. |
| src/python/tests/test_mlflow_mapping.py | Unit tests for signature/env/meta/warning helpers and reader equivalence. |
| src/python/tests/test_mlflow_verify.py | Tests for verify-mode smoke testing and _example_to_fnnx_inputs. |
| src/python/tests/test_mlflow_e2e.py | End-to-end sklearn round-trip + “no mlflow installed” packaging behavior tests. |
| src/python/tests/test_mlflow_variants.py | End-to-end tests across json/tensor/passthrough/params scenarios. |
| src/python/tests/test_mlflow_frameworks.py | End-to-end tests across XGBoost/LightGBM/CatBoost flavors. |
| src/python/tests/test_mlflow_torch.py | End-to-end tests for PyTorch flavor with/without code_paths. |
| src/python/tests/test_mlflow_tensorflow.py | End-to-end tests for Keras named-tensor inputs. |
| src/python/tests/test_mlflow_prophet.py | End-to-end tests for Prophet datetime inputs forcing json mode. |
| src/python/tests/test_mlflow_langchain.py | End-to-end tests for models-from-code via LangChain/LangGraph. |
| src/python/tests/_mlflow_fixtures/*.py | Adds fixtures used for pickle-by-reference and models-from-code e2e coverage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+20
to
+25
| import pytest | ||
|
|
||
|
|
||
| pytest.importorskip("mlflow") | ||
| pytest.importorskip("sklearn") | ||
| pytest.importorskip("pandas") |
Comment on lines
+23
to
+28
| import pytest | ||
|
|
||
|
|
||
| pytest.importorskip("mlflow") | ||
| pytest.importorskip("sklearn") | ||
| pytest.importorskip("pandas") |
Comment on lines
+24
to
+28
| import pytest | ||
|
|
||
|
|
||
| pytest.importorskip("mlflow") | ||
| pytest.importorskip("torch") |
Comment on lines
+19
to
+24
| import pytest | ||
|
|
||
|
|
||
| pytest.importorskip("mlflow") | ||
| pytest.importorskip("tensorflow") | ||
|
|
Comment on lines
+20
to
+25
| import pytest | ||
|
|
||
|
|
||
| pytest.importorskip("mlflow") | ||
| pytest.importorskip("prophet") | ||
| pytest.importorskip("pandas") |
| loader_module: str, | ||
| framework_pkg: str, | ||
| ) -> None: | ||
| pytest.importorskip(flavor) |
Comment on lines
+647
to
+649
| mlflow = pytest.importorskip("mlflow") | ||
| pytest.importorskip("sklearn") | ||
| pytest.importorskip("pandas") |
Comment on lines
+118
to
+120
| pytest.importorskip("mlflow") | ||
| pytest.importorskip("sklearn") | ||
|
|
Comment on lines
+332
to
+337
| rt = Runtime(out) | ||
| # Pass temperature, omit max_tokens (lets MLflow default apply). | ||
| result = rt.compute( | ||
| {"prompt": ["hello"]}, | ||
| {"temperature": 0.1, "max_tokens": 42}, | ||
| ) |
Comment on lines
+20
to
+24
| test = [ | ||
| "jsonschema>=4.0.0,<5.0.0", | ||
| "pydantic>=2.0.0,<3.0.0", | ||
| "pyyaml>=5.1", | ||
| "mlflow>=3.4", |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.